home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-17 | 11.8 KB | 444 lines | [TEXT/MMCC] |
- /* MPW C Application skeleton by Dean Yu */
- /* Event handling routines */
-
- // If the interfaces aren't included yet, do the standard includes. Otherwise, precompiled headers
- // have been loaded already, thank you very much
- #ifndef __TYPES__
- #include <Types.h>
- #include <AppleEvents.h>
- #include <Desk.h>
- #include <Dialogs.h>
- #include <Editions.h>
- #include <Events.h>
- #include <Menus.h>
- #include <SegLoad.h>
- #include <TextUtils.h>
- #include <ToolUtils.h>
- #include <Windows.h>
- #endif
-
- // Not in Metrowerks default precompiled headers
- #include <Editions.h>
-
- #include "FloaterSample.h"
- #include "appleEventHandlers.h"
- #include "eventHandler.h"
- #include "menuDispatch.h"
-
- /* Routine prototypes */
-
- void DoMouseEvent (EventRecord *event);
- void DoKeyEvent (EventRecord *event);
- void DoActivateEvent(EventRecord *event);
- void DoUpdateEvent (EventRecord *event);
- void DrawWindowContent(Boolean doFill);
- void DoOSEvent(EventRecord *event);
- void DoHighLevelEvent(EventRecord *event);
- void HandleGenericHighLevelEvent(EventRecord *event);
-
- /* Globals */
-
- extern Boolean gDone; /* Set to true if user selects Quit */
- extern Boolean gInBackground; /* Set to true if app is switched into background */
- extern short gTimeToDialogDismissal;
- extern Rect gDragArea; /* Area in which a window can be dragged */
- extern Rect gGrowBounds; /* Min and maximum size a window can be sized to */
- extern Boolean gNotificationPosted; // True if a notification was posted
- extern NMRec gNotificationRec; // the notification record
- extern ActivateHandlerUPP gActivateEventHandler;
-
- /*
- Fatal error alert routine.
- If an error occurs, this routine is called with the error message number
- that message is pulled from the error STR# resource, and displayed in an
- alert. The application then quits when the user clicks the “OK” button.
- */
- void FatalErrorAlert(short errID)
- {
- short alrtItem;
- Str255 errString;
-
- GetIndString(errString, rFatalErrorStringsID, errID);
- ParamText(errString, nil, nil, nil);
- alrtItem = Alert(rFatalErrorAlertID, nil);
- ExitToShell();
- }
-
- void EventLoop()
- {
- EventRecord event;
- DialogPtr theDialog;
- short itemHit;
- Boolean gotEvent;
- ProcessSerialNumber currentPSN, frontPSN;
- OSErr getFrontProcessResult, getCurrentProcessResult;
- Boolean isFrontProcess = false;
-
- // Set gInBackground appropriately
- // Compare this process and the front process
- getFrontProcessResult = GetFrontProcess(&frontPSN);
- getCurrentProcessResult = GetCurrentProcess(¤tPSN);
- if ((getFrontProcessResult == noErr) && (getCurrentProcessResult == noErr))
- SameProcess(&frontPSN, ¤tPSN, &isFrontProcess);
- gInBackground = !isFrontProcess;
-
- gDone = false;
-
- do {
- gotEvent = WaitNextEvent(everyEvent, &event, 15, nil);
- if (gotEvent) {
- if (!IsDialogEvent(&event))
- HandleEvent(&event);
- else {
- DialogSelect(&event, &theDialog, &itemHit);
- if ((itemHit == ok) || (itemHit == cancel))
- DisposeFindDialog();
-
- if (event.what == osEvt)
- DoOSEvent(&event);
- }
- }
-
- // If we’re in the background, and the find dialog is up, close it after
- // a time to demonstrate what should happen to floating windows in the background.
-
- if (gInBackground && (gTimeToDialogDismissal > 0)) {
- --gTimeToDialogDismissal;
- if (gTimeToDialogDismissal == 0)
- DisposeFindDialog();
- }
- } while (!gDone);
- ExitToShell();
- }
-
- void HandleEvent(EventRecord *event)
- {
- switch (event->what) {
- case mouseDown: DoMouseEvent(event);
- break;
- case keyDown:
- case autoKey: DoKeyEvent(event);
- break;
- case activateEvt: DoActivateEvent(event);
- break;
- case updateEvt: DoUpdateEvent(event);
- break;
- case osEvt: DoOSEvent(event);
- break;
- case kHighLevelEvent: DoHighLevelEvent(event);
- break;
-
- }
- }
-
- void DoMouseEvent(EventRecord *event)
- {
- short part;
- long growResult;
- WindowRef whichWindow;
- WindowRef frontWindow;
-
- part = FindWindow(event->where, &whichWindow);
- switch (part) {
- case inDesk: break;
- case inMenuBar: DoMenuCommand(MenuSelect(event->where));
- break;
- case inSysWindow: SystemClick(event, (WindowPtr)whichWindow);
- break;
- case inContent: frontWindow = FrontWindow();
- if (WindowIsModal(frontWindow) &&
- (whichWindow != frontWindow))
- SysBeep(1);
- else if (whichWindow != frontWindow)
- SelectReferencedWindow(whichWindow);
- else // testing, testing
- {
- Point localPt;
- ControlHandle cHandle;
- short inWhat;
-
- // might be our test modal
- SetPort((GrafPtr)GetWindowPort(whichWindow));
- localPt = event->where;
- GlobalToLocal(&localPt);
- inWhat = FindControl(localPt, whichWindow, &cHandle);
- if(inWhat == inButton && GetControlReference(cHandle) == 'DAVE')
- {
- if(TrackControl(cHandle, localPt, nil))
- {
- DisposeWindowReference(whichWindow);
- ActivateFloatersAndFirstDocumentWindow();
- }
- }
- }
- break;
- case inDrag: frontWindow = FrontWindow();
- if (WindowIsModal(frontWindow) &&
- (whichWindow != frontWindow))
- SysBeep(1);
- else
- DragReferencedWindow(whichWindow, event->where, &gDragArea);
- break;
- case inGrow: growResult = GrowWindow(whichWindow, event->where, &gGrowBounds);
- SizeWindow(whichWindow, growResult & 0x0000FFFF, (growResult & 0xFFFF0000) >> 16, true);
- break;
- case inGoAway: if (TrackGoAway(whichWindow, event->where)) {
-
- // All these bizarre cases are for testing puposes...
- if(event->modifiers & optionKey)
- {
- // Hide then show the window
- HideReferencedWindow(whichWindow);
- ShowReferencedWindow(whichWindow);
- }
- else if(event->modifiers & cmdKey)
- {
- WindowRef next = GetNextVisibleWindow(whichWindow);
-
- // Hide this window, then the next
- HideReferencedWindow(whichWindow);
- HideReferencedWindow(next);
- }
- else if(event->modifiers & shiftKey)
- {
- long dum;
- DeactivateFloatersAndFirstDocumentWindow();
- Delay(60, &dum);
- ActivateFloatersAndFirstDocumentWindow();
- }
- else if(event->modifiers & controlKey)
- {
- long dum;
- SuspendFloatingWindows();
- Delay(60, &dum);
- ResumeFloatingWindows();
- }
- else
- {
- // This is just in case multiple windows share the same
- // WindowPic, like when the program is started up with the
- // mopuse button down so that the test windows are up
- SetWindowPic(whichWindow, nil);
-
- // Dispose of the window
- DisposeWindowReference(whichWindow);
- }
-
- if(FrontNonFloatingWindow() == nil)
- DisableItem(GetMHandle(rFileMenuID), kCloseItem);
- }
- break;
- case inZoomIn:
- case inZoomOut: break;
- }
- }
-
- void DoKeyEvent(EventRecord *event)
- {
- long theKey;
-
- theKey = event->message & charCodeMask;
- if ((event->modifiers & cmdKey) && (event->what == keyDown))
- DoMenuCommand(MenuKey((char) theKey));
- }
-
- void DoActivateEvent(EventRecord *event)
- {
- Boolean activating = false;
-
- if (GetWindowKind((WindowRef) event->message) != dialogKind) {
- if (event->modifiers & activeFlag)
- activating = true;
-
- DebugStr("\pGot activate from event loop.");
-
- ActivateEventHandler((WindowRef) event->message, activating);
- }
- }
-
- pascal void ActivateEventHandler(WindowRef theWindow, Boolean activateWindow)
- {
- GrafPtr currentPort;
-
- GetPort(¤tPort);
- SetPort((GrafPtr) theWindow);
-
- DrawWindowContent(activateWindow);
-
- if (activateWindow == false)
- SetPort(currentPort);
- }
-
- pascal void RecordingFloaterActivateHandler(WindowRef theWindow, Boolean activateWindow)
- {
- GrafPtr currentPort;
- PicHandle recordingControlsPicture;
- short whichPicture;
-
- GetPort(¤tPort);
- SetPort((GrafPtr) theWindow);
-
- if (activateWindow == true)
- whichPicture = 128;
- else
- whichPicture = 129;
- recordingControlsPicture = GetPicture(whichPicture);
-
- DrawPicture(recordingControlsPicture, &((**recordingControlsPicture).picFrame));
- SetWindowPic(theWindow, recordingControlsPicture);
-
- if (activateWindow == false)
- SetPort(currentPort);
- }
-
- pascal void ToolsFloaterActivateHandler(WindowRef theWindow, Boolean activateWindow)
- {
- GrafPtr currentPort;
- PicHandle toolsPicture;
- short whichPicture;
-
- GetPort(¤tPort);
- SetPort((GrafPtr) theWindow);
-
- if (activateWindow == true)
- whichPicture = 130;
- else
- whichPicture = 131;
- toolsPicture = GetPicture(whichPicture);
-
- DrawPicture(toolsPicture, &((**toolsPicture).picFrame));
- SetWindowPic( theWindow, toolsPicture);
-
- if (activateWindow == false)
- SetPort(currentPort);
- }
-
- pascal void TestFloaterActivateHandler(WindowRef theWindow, Boolean activateWindow)
- {
- GrafPtr currentPort;
- PicHandle davePicture;
- short whichPicture;
-
- GetPort(¤tPort);
- SetPort((GrafPtr) theWindow);
-
- if (activateWindow == true)
- whichPicture = 132;
- else
- whichPicture = 133;
- davePicture = GetPicture(whichPicture);
-
- DrawPicture(davePicture, &((**davePicture).picFrame));
- SetWindowPic(theWindow, davePicture);
-
- if (activateWindow == false)
- SetPort(currentPort);
- }
-
- void DoUpdateEvent(EventRecord *event)
- {
- WindowRef theWindow = (WindowRef)event->message;
-
- SetPortWindowPort(theWindow);
- BeginUpdate(theWindow);
- if(GetExtWRefCon(theWindow) == 'DAVE')
- DrawControls(theWindow);
- else
- {
- EraseRect(&(GetWindowPort(theWindow)->portRect));
- DrawWindowContent(IsWindowHilited((WindowRef)theWindow));
- }
- EndUpdate(theWindow);
- }
-
- void DrawWindowContent(Boolean doFill)
- {
- Rect tempRect;
-
- SetRect(&tempRect, 5, 5, 50, 50);
-
- if (doFill) // == true) see notes in WindowExtensions.c
- FillRect(&tempRect, &(qd.black));
- else {
- FrameRect(&tempRect);
- InsetRect(&tempRect, 1, 1);
- EraseRect(&tempRect);
- }
- }
-
- void DoOSEvent(EventRecord *event)
- {
- switch ((event->message >> 24) & 0xFF) {
- case mouseMovedMessage: break;
- case suspendResumeMessage: if (event->message & resumeFlag) {
- gInBackground = false;
- gTimeToDialogDismissal = 0;
- DisableItem(GetMHandle(rEditMenuID), 0);
- DrawMenuBar();
- ResumeFloatingWindows();
- SetCursor(&qd.arrow);
- // Remove notification if it exists
- if(gNotificationPosted)
- {
- NMRemove(&gNotificationRec);
- gNotificationPosted = false;
- }
- }
- else {
- gInBackground = true;
- if (GetWindowKind(FrontWindow()) == dialogKind)
- gTimeToDialogDismissal = 5;
- SuspendFloatingWindows();
- }
- break;
- }
- }
-
-
- /* Handle high level events */
-
- void DoHighLevelEvent(EventRecord *event)
- {
- OSErr AEProcessResult;
-
- switch (event->message) {
- case kCoreEventClass: AEProcessResult = AEProcessAppleEvent(event); /* Handle core AppleEvents */
- break;
- case rSectionType: break; /* Handle Edition Manager AppleEvents */
- default: HandleGenericHighLevelEvent(event); /* Other high level events */
- break;
- }
- }
-
- void HandleGenericHighLevelEvent(EventRecord *event)
- {
- TargetID eventSenderInfo;
- unsigned long eventIdentifier;
- Ptr dataBuffer;
- unsigned long dataSize;
- OSErr HLEventError;
-
- dataSize = 0;
- dataBuffer = nil;
- HLEventError = AcceptHighLevelEvent(&eventSenderInfo, &eventIdentifier, dataBuffer, &dataSize);
-
- /*
- Since we don’t know how much data is coming in, call AcceptHighLevelEvent once to
- find out how much data was sent, then use create a new buffer large enough to hold
- all the data, then call AcceptHighLevelEvent again to get the data.
- */
-
- if (HLEventError == bufferIsSmall) {
- dataBuffer = NewPtr(dataSize);
- HLEventError = AcceptHighLevelEvent(&eventSenderInfo, &eventIdentifier, dataBuffer, &dataSize);
- }
-
- /* Dispatch the high level event to the proper routine depending on the message class */
-
- switch (event->message) {
- }
-
- if (dataBuffer)
- DisposPtr(dataBuffer);
- }
-